package cn.cloud9.designpattern.dp04builder;

import java.util.Arrays;

/**
 * @author OnCloud9
 * @description
 *  建造者案例 -> SQL构建器
 * @project Java
 * @date 2022年05月22日 18:30
 */
public class SqlBuilder {
    private static final String AND = "\nAND ";

    private static final String EQUAL = " = ";
    private static final String NOT_EQUAL = " != ";
    private static final String IS_NULL = " IS NULL";
    private static final String IS_NOT_NULL = " IS NOT NULL";
    private static final String ORDER_BY = " ORDER BY ";

    private String tableName;
    private String sqlPrefix = "SELECT * \nFROM ";
    private String conditionPrefix = "\nWHERE 1 = 1 ";
    private StringBuilder completeSQL = new StringBuilder(sqlPrefix);

    public SqlBuilder(String tableName) {
        this.tableName = tableName;
        this.completeSQL.append(tableName);
        this.completeSQL.append(conditionPrefix);
    }

    public SqlBuilder customCondition(String condition) {
        this.completeSQL.append(AND).append(condition);
        return this;
    }

    public SqlBuilder equal(boolean nullable, String columnName, String value) {
        if (!nullable) return this;
        this.completeSQL
                .append(AND)
                .append(columnName)
                .append(EQUAL)
                .append(value);
        return this;
    }

    public SqlBuilder notEqual(boolean nullable, String columnName, String value) {
        if (!nullable) return this;
        this.completeSQL
                .append(AND)
                .append(columnName)
                .append(NOT_EQUAL)
                .append(value);
        return this;
    }

    public SqlBuilder isNull(boolean nullable, String ... columnNames) {
        if (!nullable) return this;
        for (String columnName : columnNames) {
            this.completeSQL
                    .append(AND)
                    .append(columnName)
                    .append(IS_NULL);
        }
        return this;
    }

    public SqlBuilder isNotNull(boolean nullable, String ... columnNames) {
        if (!nullable) return this;
        for (String columnName : columnNames) {
            this.completeSQL
                    .append(AND)
                    .append(columnName)
                    .append(IS_NOT_NULL);
        }
        return this;
    }


    public SqlBuilder orderBy(String ... columns) {
        this.completeSQL.append(ORDER_BY);
        final String replace = Arrays.toString(columns).replace("[", "").replace("]", "");
        this.completeSQL.append(replace);
        return this;
    }

    public SqlBuilder orderByDesc(String ... columns) {
        this.completeSQL.append(ORDER_BY);
        for (int i = 0; i < columns.length; i++) {
            columns[i] += " DESC";
        }
        final String replace = Arrays.toString(columns).replace("[", "").replace("]", "");
        this.completeSQL.append(replace);
        return this;
    }

    public String getSQL() {
        return this.completeSQL.toString();
    }

    public static void main(String[] args) {
        final SqlBuilder sqlBuilder = new SqlBuilder("tm_part_info");
        final String sql = sqlBuilder
                .equal(true, "STATUS", "1")
                .isNotNull(true, "PART_NO", "ORG_ID", "UPDATE_BY")
                .orderBy("CREATE_DATE", "PART_NO").getSQL();
        System.out.println(sql);
    }


}
